<?php

namespace Iwester\Http\Model\Article;

use Iwester\Http\Model\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
use Iwester\Http\Model\Config\SiteConfig;
use Iwester\Http\Model\User\User;

/**
 * Article Entity
 *
 * @property int $id
 * @property string $title
 * @property string $subtitle
 * @property string $content
 * @property int $article_category_id
 * @property int $user_id
 * @property int $view_count
 * @property string $cover
 * @property int $status
 * @property int $source_type
 * @property int $source_id
 * @property string $published_at
 */
class Article extends Base
{
    use SoftDeletes;

    const PUBLISH = 1; //公开
    const DRAFT = 0; // 隐私

    const AUDIT_FAIL = -1;  // 审核不通过
    const AUDIT_WAIT = 0;  // 待审核
    const AUDIT_PASS = 1;  // 审核通过

    protected $appends = ['seo', 'detail_url'];
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'title', 'subtitle', 'summary', 'article_category_id', 'cover', 'published_at', 'user_id', 'view_count', 'audit_status', 'published_at', 'publish_status'
    ];

    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array
     */
    protected $_accessible = [
        '*' => true,
        'id' => false
    ];

    /**
     * 获取文章详情url
     */
    public function getDetailUrlAttribute()
    {
        $prefix = $this->articleCategory->prefix;
        $router = $prefix.'.detail';
        return route($router, ['id'=> $this->id]);
    }


    /**
     * 获得此文章的评论。
     */
    public function comments()
    {
        return $this->hasMany(ArticleComment::class);
    }

    /**
     * 获得此文章 - 点赞数据。
     */
    public function articleZan()
    {
        return $this->hasMany(ArticleLike::class, 'article_id', 'id');
    }

    //与标签多对多关联
    public function tags()
    {
        return $this->belongsToMany('Iwester\Http\Model\Article\ArticleTag', 'article_tag_pivot', 'article_id', 'article_tag_id');
    }

    /**
     * 获取文章发布者
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }

    /**
     * 获取文章标签
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function articleTags()
    {
        return $this->hasMany(ArticleTagPivot::class, 'article_id');
    }

    /**
     * 获取文章类目
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function articleCategory()
    {
        return $this->hasOne(ArticleCategory::class, 'id', 'article_category_id');
    }

    /**
     * 获取文章内容
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function articleContent()
    {
        return $this->hasOne(ArticleContent::class, 'article_id', 'id');
    }

    /**
     * 获取文章
     * @param array $whereArr 筛选条件
     * @param array $orderBy 排序条件
     * @param int $pageSize 每页数量
     * @param int $pageType 是否分页
     * @return Article[]|\Illuminate\Contracts\Pagination\LengthAwarePaginator|\Illuminate\Database\Eloquent\Collection
     */
    public static function getArticleData($whereArr = [], $orderBy = [['id' => 'desc']], $pageSize = 10, $paginate = true, $inArr = [], $showAll = false)
    {
        $articleQuery = Article::with(['user','articleCategory'])->select(['*']);
        if ($whereArr) $articleQuery->where($whereArr);
        if ($inArr) $articleQuery->whereIn($inArr[0], $inArr[1]);
        if ($orderBy) {
            foreach ($orderBy as $column => $type) {
                if (is_array($type)) {
                    foreach ($type as $columnSub => $typeSub) {
                        $articleQuery->orderBy($columnSub, $typeSub);
                    }
                } else {
                    $articleQuery->orderBy($column, $type);
                }
            }
        }
        if ($showAll) $articleQuery->withTrashed();
        if ($paginate) {
            return $articleQuery->paginate($pageSize);
        } else {
            return $articleQuery->limit($pageSize)->get();
        }
    }

    /**
     * 保存文章
     * @param $title
     * @param $content
     * @param $articleCategoryId
     * @param $publishedAt
     * @param int $status
     * @param string $cover
     * @param int $sourceType
     * @param int $sourceId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|Article|null|object
     * @throws \Exception
     */
    public static function stroe($title, $content, $articleCategoryId, $publishedAt, $status = 0, $cover = '', $sourceType = 0, $sourceId = 0)
    {
        try {
            $article = Article::where('title', $title)->first();
            if ($article) return $article;
            $article = new Article();
            $article->title = $title;
            $article->content = $content;
            $article->article_category_id = $articleCategoryId;
            $article->user_id = 1;
            $article->cover = $cover;
            $article->status = $status;
            $article->published_at = $publishedAt;
            $article->source_type = $sourceType;
            $article->source_id = $sourceId;
            $article->save();
            return $article;
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 公开状态
     * @return string
     */
    public function getPublishStatus()
    {
        switch ($this->publish_status) {
            case self::PUBLISH:
                return '公开';
            default:
                return '隐私';
        }
    }

    /**
     * 审核状态
     * @return string
     */
    public function getAuditStatus()
    {
        switch ($this->audit_status) {
            case self::AUDIT_PASS:
                return '审核通过';
            case self::AUDIT_WAIT:
                return '待审核';
            default:
                return '不通过';
        }
    }

    /**
     * 获取上一篇
     * @param $id
     * @param $currentCategory
     * @return mixed
     */
    public function prevArticle($currentCategory = false)
    {
        if (!$currentCategory) {
            $currentCategory = $this->articleCategory->parentCate;
        }
        return Article::getArticleData([['id', '<', $this->id]], [['id' => 'desc']], 1, false, ['article_category_id', json_decode($currentCategory->sub_category)])->first();
    }

    /**
     * 获取下一篇
     * @param $id
     * @param $currentCategory
     * @return mixed
     */
    public function nextArticle($currentCategory = false)
    {
        if (!$currentCategory) {
            $currentCategory = $this->articleCategory->parentCate;
        }
        return Article::getArticleData([['id', '>', $this->id]], [['id' => 'asc']], 1, false, ['article_category_id', json_decode($currentCategory->sub_category)])->first();
    }

    /**
     * 获取文章封面
     */
    public function getCover()
    {
        if ((@fopen($this->cover, "r") || file_exists(public_path() . $this->cover)) && $this->cover != '' && $this->cover) {
            return $this->cover;
        } else {
            if (strpos($this->content, 'src') !== false) {
                return explode('"', explode('src="', $this->content)[1])[0];
            } else {
                return "/static/images/article_avatar.png";
            }
        }
    }

    /**
     * 根据栏目规则重新渲染TDK
     * @return object
     */
    public function getSeoAttribute()
    {
        $cate = $this->articleCategory;
        $seo['title'] = $this->articleContent->title ? $this->articleContent->title : $this->replaceCon($cate->title_rule, $this, 'title');
        $seo['keyword'] = $this->articleContent->keyword ? $this->articleContent->keyword : $this->replaceCon($cate->keyword_rule, $this, 'keyword');
        $seo['description'] = $this->articleContent->description ? $this->articleContent->description : $this->replaceCon($cate->description_rule, $this, 'description');
        return (object)$seo;
    }

    /**
     * 根据规则替换TDK
     * @param $rule
     * @param $article
     * @param $type
     * @return bool|mixed
     */
    private function replaceCon($rule, $article, $type)
    {
        if ($rule == '') $rule = ArticleCategory::$articleRules[$type]; # 如果分类没有规则 - 使用默认规则
        $content = mb_substr(strip_tags($article->articleContent->content), 0, 80); //内容简介
        $content = str_replace(" ", '', $content);
        $content = str_replace("\r\n", '', $content);
        $replaceDatas = [
            '{文章标题}' => $article->title,
            '{文章分类}' => $article->articleCategory->cate_name,
            '{网站名称}' => SiteConfig::getConfig()->site_name,
            '{分类SEO关键词}' => $article->articleCategory->keyword,
            '{内容简介}' => $content != '' ? $content : $article->title
        ];
        foreach (ArticleCategory::$rules[$type] as $r) {
            $rule = str_replace($r, isset($replaceDatas[$r]) ? $replaceDatas[$r] : '', $rule);
        }
        return $rule;
    }


}
